package com.sojson.util.param;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import com.sojson.base.impl.BaseUser;
import com.sojson.config.exception.TransErrorCode;
import com.sojson.constant.DataScopeType;
import com.sojson.enums.core.ERoleType;
import com.sojson.project.sys.role.entity.vo.RoleVo;
import com.sojson.util.ExpUtil;
import com.sojson.util.StringUtil;
import com.sojson.util.token.Token;
import com.sojson.util.token.TokenUtil;

/**
 * 参数管理工具类
 * 
 * @author liu
 * @date 2020-11-02
 */
public class ParamUtil {

    /**
     * 是否登录
     * 
     * @throws IOException
     */
    public static boolean isLogin() throws IOException {
        return isLogin(TokenUtil.getToken());
    }

    /**
     * 是否登录
     * 
     * @param token
     * @throws IOException
     */
    public static boolean isLogin(Token token) throws IOException {
        // 判断Token是否为空
        if (StringUtil.isBlankObject(token)) {
            return false;
        }

        BaseUser user = token.getUser();
        // 判断用户是否为空
        if (StringUtil.isBlankObject(user)) {
            return false;
        }

        // 判断Token是否过期
        if (!TokenUtil.verifyToken(token)) {
            return false;
        }

        return true;
    }

    /**
     * 是否是超级管理员
     * 
     * @return
     * @throws IOException 
     */
    public static boolean isAdminSuper() throws IOException {
        return isAdminSuper(TokenUtil.getRoles());
    }

    /**
     * 是否是超级管理员
     * 
     * @param key
     * @return
     */
    public static boolean isAdminSuper(String key) {
        return ERoleType.ADMIN_SUPER.getKey().equals(key);
    }

    /**
     * 是否是超级管理员
     * 
     * @param token
     * @return
     * @throws IOException 
     */
    public static boolean isAdminSuper(Token token) throws IOException {
        return isAdminSuper(token.getRoles());
    }

    /**
     * 是否是超级管理员
     * 
     * @param roles
     * @return
     */
    public static boolean isAdminSuper(Collection<String> roles) {
        return roles.contains(ERoleType.ADMIN_SUPER.getKey());
    }

    /**
     * 是否是超级管理员
     * 
     * @param roles
     * @return
     */
    public static boolean isAdminSuper(List<RoleVo> roles) {
        String key = ERoleType.ADMIN_SUPER.getKey();

        for (RoleVo roleVo : roles) {
            if (key.equals(roleVo.getKey())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 是否拥有角色
     * 
     * @param role
     * @return
     * @throws IOException 
     */
    public static boolean isRole(String role) throws IOException {
        return isPerm(TokenUtil.getRoles(), role);
    }

    /**
     * 是否拥有角色
     * 
     * @param id
     * @return
     * @throws IOException 
     */
    public static boolean isRoleId(String id) throws IOException {
        return isPerm(TokenUtil.getRoleIds(), id);
    }

    /**
     * 是否拥有角色
     * 
     * @param ids
     * @return
     * @throws IOException 
     */
    public static boolean isRoleId(Set<String> ids) throws IOException {
        return isPerm(TokenUtil.getRoleIds(), ids);
    }

    /**
     * 是否拥有角色ID
     * 
     * @param id
     * @return
     * @throws IOException 
     */
    public static boolean isRoleIdExist(String id) throws IOException {
        return isPerm(TokenUtil.getRoleIdsExist(), id);
    }

    /**
     * 是否拥有角色ID
     * 
     * @param ids
     * @return
     * @throws IOException 
     */
    public static boolean isRoleIdExist(Set<String> ids) throws IOException {
        return isPerm(TokenUtil.getRoleIdsExist(), ids);
    }

    /**
     * 是否拥有菜单
     * 
     * @param perm
     * @return 
     * @throws IOException
     */
    public static boolean isPerm(String perm) throws IOException {
        return isPerm(TokenUtil.getPerms(), perm);
    }

    /**
     * 是否拥有菜单
     * 
     * @param perms
     * @return 
     * @throws IOException
     */
    public static boolean isPerm(Set<String> perms) throws IOException {
        return isPerm(TokenUtil.getPerms(), perms);
    }

    /**
     * 是否拥有菜单ID
     * 
     * @param permId
     * @return 
     * @throws IOException
     */
    public static boolean isMenuId(String permId) throws IOException {
        return isPerm(TokenUtil.getPermIds(), permId);
    }

    /**
     * 是否拥有权限
     * 
     * @param permsLogin    当前用户的权限
     * @param perms         要校验的权限
     * @return
     * @throws IOException 
     */
    private static boolean isPerm(Set<String> permsLogin, String perm) throws IOException {
        if (isAdminSuper()) {
            return true;
        }

        if (StringUtil.isBlankString(perm)) {
            return false;
        }

        if (permsLogin.contains(perm)) {
            return true;
        }

        return false;
    }

    /**
     * 是否拥有权限
     * 
     * @param permsLogin    当前用户的权限
     * @param perms         要校验的权限
     * @return
     * @throws IOException 
     */
    private static boolean isPerm(Set<String> permsLogin, Set<String> perms) throws IOException {
        if (isAdminSuper()) {
            return true;
        }

        if (perms == null || perms.size() < 1) {
            return false;
        }

        if (permsLogin.containsAll(perms)) {
            return true;
        }

        return false;
    }

    /**
     * 是否拥有部门
     * 
     * @param deptId
     * @return 
     * @throws IOException
     */
    public static boolean isDept(String deptId) throws IOException {
        if (isAdminSuper()) {
            return true;
        }

        Integer dataScope = TokenUtil.getUser().getDataScope();

        if (dataScope == DataScopeType.DATA_SCOPE_ALL) {
            return true;
        }

        if (dataScope == DataScopeType.DATA_SCOPE_SELF) {
            return false;
        }

        if (StringUtil.isBlankString(deptId)) {
            return false;
        }

        if (TokenUtil.getDepts().contains(deptId)) {
            return true;
        }

        return false;
    }

    /**
     * 是否拥有部门
     * 
     * @param deptIds
     * @throws IOException
     */
    public static boolean isDept(Set<String> deptIds) throws IOException {
        if (isAdminSuper()) {
            return true;
        }

        Integer dataScope = TokenUtil.getUser().getDataScope();

        if (dataScope == DataScopeType.DATA_SCOPE_ALL) {
            return true;
        }

        if (dataScope == DataScopeType.DATA_SCOPE_SELF) {
            return false;
        }

        if (deptIds == null || deptIds.size() < 1) {
            return false;
        }

        if (TokenUtil.getDepts().containsAll(deptIds)) {
            return true;
        }

        return false;
    }

    /**
     * 是否登录
     * 
     * @throws IOException
     */
    public static void verifyLogin() throws IOException {
        if (!isLogin()) {
            ExpUtil.throwEx(TransErrorCode.NOT_LOGIN);
        }
    }

    /**
     * 是否登录
     * 
     * @param token
     * @throws IOException
     */
    public static void verifyLogin(Token token) throws IOException {
        if (!isLogin(token)) {
            ExpUtil.throwEx(TransErrorCode.NOT_LOGIN);
        }
    }

    /**
     * 是否拥有角色
     * 
     * @param role
     * @throws IOException
     */
    public static void verifyRole(String role) throws IOException {
        verifyPerm(TokenUtil.getRoles(), role);
    }

    /**
     * 是否拥有角色
     * 
     * @param roleId
     * @throws IOException
     */
    public static void verifyRoleIdExist(String roleId) throws IOException {
        verifyRole(TokenUtil.getRoleIdsExist(), roleId);
    }

    /**
     * 是否拥有角色
     * 
     * @param roleIds
     * @throws IOException
     */
    public static void verifyRoleIdExist(Set<String> roleIds) throws IOException {
        verifyRole(TokenUtil.getRoleIdsExist(), roleIds);
    }

    /**
     * 是否拥有权限
     * 
     * @param roleLogin
     * @param role
     * @throws IOException
     */
    private static void verifyRole(Set<String> roleLogin, String role) throws IOException {
        if (!isPerm(roleLogin, role)) {
            ExpUtil.throwEx(TransErrorCode.NOT_ROLE_PERMISSION);
        }
    }

    /**
     * 是否拥有权限
     * 
     * @param roleLogin
     * @param role
     * @throws IOException
     */
    private static void verifyRole(Set<String> roleLogin, Set<String> role) throws IOException {
        if (!isPerm(roleLogin, role)) {
            ExpUtil.throwEx(TransErrorCode.NOT_ROLE_PERMISSION);
        }
    }

    /**
     * 是否拥有菜单ID
     * 
     * @param permId
     * @throws IOException
     */
    public static void verifyMenuIdExist(String permId) throws IOException {
        verifyPerm(TokenUtil.getPermIdsExist(), permId);
    }

    /**
     * 是否拥有权限
     * 
     * @param perm
     * @throws IOException
     */
    public static void verifyPerm(String perm) throws IOException {
        verifyPerm(TokenUtil.getPerms(), perm);
    }

    /**
     * 是否拥有权限
     * 
     * @param perms
     * @throws IOException
     */
    public static void verifyPerm(Set<String> perms) throws IOException {
        verifyPerm(TokenUtil.getPerms(), perms);
    }

    /**
     * 是否拥有权限
     * 
     * @param permsLogin
     * @param perm
     * @throws IOException
     */
    private static void verifyPerm(Set<String> permsLogin, String perm) throws IOException {
        if (!isPerm(permsLogin, perm)) {
            ExpUtil.throwEx(TransErrorCode.NOT_PERM_PERMISSION);
        }
    }

    /**
     * 是否拥有权限
     * 
     * @param permsLogin
     * @param perms
     * @throws IOException
     */
    public static void verifyPerm(Set<String> permsLogin, Set<String> perms) throws IOException {
        if (!isPerm(permsLogin, perms)) {
            ExpUtil.throwEx(TransErrorCode.NOT_PERM_PERMISSION);
        }
    }

    /**
     * 是否拥有部门
     * 
     * @param deptId
     * @throws IOException
     */
    public static void verifyDept(String deptId) throws IOException {
        if (!isDept(deptId)) {
            ExpUtil.throwEx(TransErrorCode.NOT_DEPT_PERMISSION);
        }
    }

    /**
     * 是否拥有部门
     * 
     * @param deptIds
     * @throws IOException
     */
    public static void verifyDept(Set<String> deptIds) throws IOException {
        if (!isDept(deptIds)) {
            ExpUtil.throwEx(TransErrorCode.NOT_DEPT_PERMISSION);
        }
    }

}